﻿using System;
using System.Collections.Generic;
using System.Text;
using MYLSOFT.JsonSimple;
using com.byt.webcore.utils;
using com.byt.suce.db.mapper;
using com.byt.suce.db.factory;
using System.Data.Common;
using com.byt.webcore.utils.ext;
using System.Net;
using System.Web;

namespace com.byt.webcore.security
{
    class Security
    {

        
    private static string COOKIE_SECURITY_NAME = "byt";
    private static int COOKIE_SECURITY_MAXAGE = 60 * 60 * 24 * 7; // 1 semana
    private static string COOKIE_SECURITY_PATH = "/";

    private Security() {
    }

    /*
     * Validar la Contraseña
     */

    public static bool isPasswordValid(string password, string hash, string salt) {
        try {
            return PasswordHasher.isValid(password, hash, salt);
        } catch (Exception ex) {
            return false;
        }
    }


    /*
     * Validar el inicio de sesion
     */

    public static JSONObject loginUser(ServletBase.Parameters p) {

        PkgSeguridad.UserLoginParam param = PkgSeguridadFactory.create().newUserLoginParam(p.getMap());
        param.Usrname = p.getParameter("mlkuser");
        PkgSeguridadFactory.create().userLogin(p.conn, param);
        //p.conn.Commit();

        DbDataReader rs = param.CurOut;
        rs.Read();
        JSONObject SysConfig = Utils.getJSONObject(rs);
        rs.Close();

        string error = "";
        if (SysConfig.Count >0) {

            // verificar si la cuenta no esta bloqueada
            if ("1".Equals(SysConfig["fglock"]))
                throw new Exception("Cuenta bloqueda por intentos fallidos de autenticación");

            // Validar la Contraseña
            string password = p.getParameter("mlkpass");
            string salt = (string)SysConfig["vcpasssalt"];
            string hash = (string)SysConfig["vcpass"];
            if(!password.Equals(hash)) {
                throw new Exception("Usuario o contraseña inválida");
            }
            /*
            if (!Security.isPasswordValid(password, hash, salt)) {
                throw new Exception("Usuario o contraseña inválida.");
            }
             * */

            Object dummy = SysConfig["diasfaltan"];
            string dias_faltan = "";
            if (dummy != null)
                dias_faltan = dummy.ToString();
            if (string.IsNullOrEmpty(dias_faltan))
                dias_faltan = " ";

            if ("0".Equals(SysConfig["fgactivo"].ToString())) {
                error = "La cuenta del usuario esta inactiva.";
            } else if ("1".Equals((string)SysConfig["fgbaja"])) {
                error = "La cuenta del usuario esta dado de Baja.";
            } else if ("-".Equals(dias_faltan.Substring(0, 1))) {
                error = "La cuenta del usuario ha expirado.";
            } else {

                SysConfig.Remove("vcpasssalt");
                SysConfig.Remove("vcpass");
                SysConfig.Remove("fgactivo");
                SysConfig.Remove("diasfaltan");
                SysConfig.Remove("fglock");
                return SysConfig;

            }

        } else {
            throw new Exception("Usuario o contraseña inválida.");
        }

        if (error.Length > 0) {
            throw new Exception(error);
        }
        return null;
    }

    /*
     * Leer los datos asociados a un usuario que inicio sesion
     */

    public static JSONObject getUserData(ServletBase.Parameters p) {

        PkgSeguridad.UserGetdataParam param = PkgSeguridadFactory.create().newUserGetdataParam(p.getMap());
        param.Iduser=p.iduser;
        PkgSeguridadFactory.create().userGetdata(p.conn, param);

        DbDataReader rsHeader = param.CurHeader;
        DbDataReader rsMenu = param.CurMenu;
        DbDataReader rsStartMenu = param.CurStartmenu;

        /*
        Leer los datos
        */
        JSONObject result = Utils.getJSONObject(rsHeader);

        // Guardar en la cache solo los datos del usuario (no los demas datos)
        /*
        if(saveInCache){
            cache.setUser(iduser.toString(), result);
        }
        */


        /*
         * Leer el Menu
         */
        Menu mnu = new Menu(rsMenu);
        result.Add("menu", mnu);

        /*
         * Leer el Menu
         */
        Menu startMenu = new Menu(rsStartMenu);
        result.Add("startMenu", startMenu);


        rsHeader.Close();
        rsMenu.Close();
        rsStartMenu.Close();

        return result;
    }

    public static JSONObject getUserFromStringEncrypt(ServletBase.Parameters p, string value) {
        value = Encoding.UTF8.GetString(Encrypt.decrypt(p, Utils.HexToBytes(value)));

        JSONObject user = (JSONObject)JSONValue.Parse(value);
        user.Add("iduser", user["u"]);
        user.Add("idadmuser", user["a"]);
        user.Add("idorgentidad", user["o"]);
        user.Add("iduorganica", user["uo"]);
        if (user.ContainsKey("r"))
            user.Add("rememberme", user["r"]);

        user.Remove("u");
        user.Remove("a");
        user.Remove("r");
        user.Remove("o");
        user.Remove("uo");
        return user;
    }

    public static JSONObject getUserFromCookie(ServletBase.Parameters p) {
        try {
            p.iduser = null;
            p.idadmuser = null;
            HttpCookieCollection co = p.req.Cookies;
            if (co != null) {
                foreach (string c in co)
                {
                    HttpCookie cookie = co[c];
                    if (cookie.Name.Equals(Security.COOKIE_SECURITY_NAME)) {

                        string value = cookie.Value;

                        if (!string.IsNullOrEmpty(value)) {
                            JSONObject user = getUserFromStringEncrypt(p, value);
                            return user;
                        }
                    }

                }

            }
        } catch {
            //ex.printStackTrace();
        }
        return null;
    }

    public static void setUserToCookie(ServletBase.Parameters p, JSONObject value) {

        if (value == null)
            return;

        try {
            string rememberme = p.getParameter("rememberme");
            JSONObject jo = new JSONObject();

            jo.Add("u", value["iduser"]);
            jo.Add("a", value["idadmuser"]);
            jo.Add("o", value["idorgentidad"]);
            jo.Add("uo", value["iduorganica"]);
            jo.Add("iduservuce", value["iduservuce"]);
            jo.Add("r", rememberme);

            string val = Utils.BytesToHex(Encrypt.encrypt(p, jo.ToString()));

            HttpCookie c = new HttpCookie(Security.COOKIE_SECURITY_NAME, val);

            c.Path = Security.COOKIE_SECURITY_PATH;

            if (!string.IsNullOrEmpty(rememberme)) {
                c.Expires = DateTime.Now.AddSeconds(Security.COOKIE_SECURITY_MAXAGE);
            }

            p.res.Cookies.Add(c);

        } catch {
            //ex.printStackTrace();
        }
    }

    }
}
